package com.wlcorp.forcazamis.sys.util;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Date;

@SuppressWarnings("unchecked")
public class ReflectUtil {
	public static Object createObject(String className){
		Class cls = null;
		Object obj = null;
		Class[] clsArray = new Class[]{};
		Object[] objArray = new Object[]{};
		try {
			cls = Class.forName(className);
			Constructor constructor = cls.getDeclaredConstructor(clsArray);
			obj = constructor.newInstance(objArray);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return obj;
	}
	
	public static Object invokeMethod(Object obj,String methodName,Object[] params){
		Object result = null;
		Method[] methods = obj.getClass().getDeclaredMethods();
		Method method = null;
		for (int i = 0; i < methods.length; i++) {
			if(methods[i].getName().equals(methodName) && params.length == methods[i].getParameterTypes().length){
				method = methods[i];
				break;
			}
		}
		if(null == method){
			methods = obj.getClass().getSuperclass().getDeclaredMethods();
			for (int i = 0; i < methods.length; i++) {
				if(methods[i].getName().equals(methodName) && params.length == methods[i].getParameterTypes().length){
					method = methods[i];
					break;
				}
			}
			
		}
		if(null == method){
			//错误处理
			System.out.println("Error:方法不存在!");
			return null;
		}
		try {
			result = method.invoke(obj,params);
		} catch (IllegalArgumentException e) {
			System.out.println("IllegalArgumentException Error:methodName=" + method.getName());
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	public static Object getAttributeValue(Object obj,String attributeName){
		String methodName = "get" + attributeName.substring(0,1).toUpperCase() + attributeName.substring(1,attributeName.length());
		Object[] params = new Object[]{};
		return invokeMethod(obj,methodName,params);
	}
	
	public static void setAttributeValue(Object obj,String attributeName,Object value){
		String methodName = "set" + attributeName.substring(0,1).toUpperCase() + attributeName.substring(1,attributeName.length());
		
		Class paramType = getMethodParamType(obj,methodName);
		if(null == paramType){
			return;
		}
		value = convertToCorrectType(value,paramType);
		Object[] params = new Object[]{value};
		invokeMethod(obj,methodName,params);
	}
	
	public static Object convertToCorrectType(Object from,Class to){
		Object result = from;
		String fromStr = String.valueOf(from);
		if(!isValid(fromStr)){
			return null;
		}
		try{
			if(Double.class.getName().equals(to.getName())){
				result = Double.valueOf(fromStr);
			} else if(Float.class.getName().equals(to.getName())){
				result = Float.valueOf(fromStr);
			} else if(Integer.class.getName().equals(to.getName())){
				result = Integer.valueOf(fromStr);
			} else if(Long.class.getName().equals(to.getName())){
				result = Long.valueOf(fromStr);
			} else if(Date.class.getName().equals(to.getName())){
				result = Date.valueOf(fromStr);
			} 
			if(to.isArray() && !from.getClass().isArray()){
				Object tmpResult = Array.newInstance(from.getClass(), 1);
				Array.set(tmpResult, 0, result);
				result = tmpResult;
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}
		return result;
	}
	
	public static Class getMethodParamType(Object obj,String methodName){
		Class result = null;
		Method[] methods = obj.getClass().getDeclaredMethods();
		for (int i = 0; i < methods.length; i++) {
			if(methods[i].getName().equals(methodName)  && 1 == methods[i].getParameterTypes().length){
				result = methods[i].getParameterTypes()[0];
			}
		}
		if(null == result){
			methods = obj.getClass().getSuperclass().getDeclaredMethods();
			for (int i = 0; i < methods.length; i++) {
				if(methods[i].getName().equals(methodName) && 1 == methods[i].getParameterTypes().length){
					result = methods[i].getParameterTypes()[0];
				}
			}
		}
		return result;
	}
	
	private static boolean isValid(Object obj){
		String objStr = String.valueOf(obj);
		if(null == objStr || "".equals(objStr) || "null".equals(objStr)){
			return false;
		}
		return true;
	}
}
